import os
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
                             QPushButton, QFileDialog, QSpinBox, QComboBox,
                             QGroupBox, QProgressBar, QTextEdit, QMessageBox,
                             QSlider, QCheckBox, QLineEdit, QFrame)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
from PyQt5.QtGui import QFont, QColor

from app.core.subtitle_extractor import SubtitleExtractor, SubtitleExtractionThread


class SubtitleExtractorWidget(QWidget):
    """字幕提取界面"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.extractor = SubtitleExtractor()
        self.extraction_thread = None
        self.init_ui()
        
        # 连接OCR引擎状态信号
        self.extractor.status_updated.connect(self.update_ocr_status)
        
    def init_ui(self):
        """初始化用户界面"""
        layout = QVBoxLayout()
        
        # 标题
        title_label = QLabel("视频字幕提取工具")
        title_label.setFont(QFont("Arial", 16, QFont.Bold))
        title_label.setAlignment(Qt.AlignCenter)
        layout.addWidget(title_label)
        
        # OCR引擎状态组
        ocr_group = QGroupBox("OCR引擎状态")
        ocr_layout = QVBoxLayout()
        
        self.ocr_status_label = QLabel("正在初始化OCR引擎...")
        self.ocr_status_label.setStyleSheet("color: orange; font-weight: bold;")
        ocr_layout.addWidget(self.ocr_status_label)
        
        ocr_group.setLayout(ocr_layout)
        layout.addWidget(ocr_group)
        
        # 文件选择组
        file_group = QGroupBox("文件选择")
        file_layout = QVBoxLayout()
        
        # 输入视频
        video_layout = QHBoxLayout()
        video_layout.addWidget(QLabel("输入视频:"))
        self.video_path_edit = QLineEdit()
        self.video_path_edit.setPlaceholderText("选择要提取字幕的视频文件")
        video_layout.addWidget(self.video_path_edit)
        self.select_video_btn = QPushButton("浏览")
        self.select_video_btn.clicked.connect(self.select_video)
        video_layout.addWidget(self.select_video_btn)
        file_layout.addLayout(video_layout)
        
        # 输出字幕
        output_layout = QHBoxLayout()
        output_layout.addWidget(QLabel("输出字幕:"))
        self.output_path_edit = QLineEdit()
        self.output_path_edit.setPlaceholderText("选择字幕文件保存位置")
        output_layout.addWidget(self.output_path_edit)
        self.select_output_btn = QPushButton("浏览")
        self.select_output_btn.clicked.connect(self.select_output)
        output_layout.addWidget(self.select_output_btn)
        file_layout.addLayout(output_layout)
        
        file_group.setLayout(file_layout)
        layout.addWidget(file_group)
        
        # 提取参数组
        params_group = QGroupBox("提取参数")
        params_layout = QVBoxLayout()
        
        # 采样间隔
        interval_layout = QHBoxLayout()
        interval_layout.addWidget(QLabel("采样间隔:"))
        self.interval_spin = QSpinBox()
        self.interval_spin.setRange(1, 10)
        self.interval_spin.setValue(2)
        self.interval_spin.setSuffix(" 秒")
        interval_layout.addWidget(self.interval_spin)
        interval_layout.addStretch()
        params_layout.addLayout(interval_layout)
        
        # 置信度阈值
        confidence_layout = QHBoxLayout()
        confidence_layout.addWidget(QLabel("置信度阈值:"))
        self.confidence_slider = QSlider(Qt.Horizontal)
        self.confidence_slider.setRange(30, 90)
        self.confidence_slider.setValue(60)
        self.confidence_slider.setTickPosition(QSlider.TicksBelow)
        self.confidence_slider.setTickInterval(10)
        confidence_layout.addWidget(self.confidence_slider)
        self.confidence_label = QLabel("60%")
        self.confidence_slider.valueChanged.connect(
            lambda v: self.confidence_label.setText(f"{v}%")
        )
        confidence_layout.addWidget(self.confidence_label)
        params_layout.addLayout(confidence_layout)
        
        # 字幕区域设置
        region_layout = QHBoxLayout()
        self.auto_detect_checkbox = QCheckBox("自动检测字幕区域")
        self.auto_detect_checkbox.setChecked(True)
        self.auto_detect_checkbox.toggled.connect(self.toggle_region_settings)
        region_layout.addWidget(self.auto_detect_checkbox)
        region_layout.addStretch()
        params_layout.addLayout(region_layout)
        
        # 手动设置字幕区域
        self.region_frame = QFrame()
        self.region_frame.setVisible(False)
        region_settings_layout = QVBoxLayout()
        
        # 字幕区域坐标
        coords_layout = QHBoxLayout()
        coords_layout.addWidget(QLabel("字幕区域:"))
        coords_layout.addWidget(QLabel("X:"))
        self.x_spin = QSpinBox()
        self.x_spin.setRange(0, 9999)
        self.x_spin.setValue(0)
        coords_layout.addWidget(self.x_spin)
        
        coords_layout.addWidget(QLabel("Y:"))
        self.y_spin = QSpinBox()
        self.y_spin.setRange(0, 9999)
        self.y_spin.setValue(0)
        coords_layout.addWidget(self.y_spin)
        
        coords_layout.addWidget(QLabel("宽度:"))
        self.width_spin = QSpinBox()
        self.width_spin.setRange(100, 9999)
        self.width_spin.setValue(800)
        coords_layout.addWidget(self.width_spin)
        
        coords_layout.addWidget(QLabel("高度:"))
        self.height_spin = QSpinBox()
        self.height_spin.setRange(50, 9999)
        self.height_spin.setValue(100)
        coords_layout.addWidget(self.height_spin)
        
        coords_layout.addStretch()
        region_settings_layout.addLayout(coords_layout)
        
        # 预设区域按钮
        preset_layout = QHBoxLayout()
        preset_layout.addWidget(QLabel("预设区域:"))
        
        self.bottom_center_btn = QPushButton("底部中央")
        self.bottom_center_btn.clicked.connect(lambda: self.set_preset_region("bottom_center"))
        preset_layout.addWidget(self.bottom_center_btn)
        
        self.bottom_full_btn = QPushButton("底部全宽")
        self.bottom_full_btn.clicked.connect(lambda: self.set_preset_region("bottom_full"))
        preset_layout.addWidget(self.bottom_full_btn)
        
        self.top_center_btn = QPushButton("顶部中央")
        self.top_center_btn.clicked.connect(lambda: self.set_preset_region("top_center"))
        preset_layout.addWidget(self.top_center_btn)
        
        preset_layout.addStretch()
        region_settings_layout.addLayout(preset_layout)
        
        self.region_frame.setLayout(region_settings_layout)
        params_layout.addWidget(self.region_frame)
        
        # 高级选项
        advanced_layout = QHBoxLayout()
        self.merge_adjacent_checkbox = QCheckBox("合并相邻字幕")
        self.merge_adjacent_checkbox.setChecked(True)
        advanced_layout.addWidget(self.merge_adjacent_checkbox)
        
        self.show_preview_checkbox = QCheckBox("显示提取预览")
        self.show_preview_checkbox.setChecked(True)
        advanced_layout.addWidget(self.show_preview_checkbox)
        advanced_layout.addStretch()
        params_layout.addLayout(advanced_layout)
        
        params_group.setLayout(params_layout)
        layout.addWidget(params_group)
        
        # 视频信息组
        info_group = QGroupBox("视频信息")
        info_layout = QVBoxLayout()
        
        self.video_info_text = QTextEdit()
        self.video_info_text.setMaximumHeight(100)
        self.video_info_text.setPlaceholderText("选择视频文件后显示视频信息")
        info_layout.addWidget(self.video_info_text)
        
        info_group.setLayout(info_layout)
        layout.addWidget(info_group)
        
        # 进度组
        progress_group = QGroupBox("提取进度")
        progress_layout = QVBoxLayout()
        
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        progress_layout.addWidget(self.progress_bar)
        
        self.status_text = QTextEdit()
        self.status_text.setMaximumHeight(120)
        self.status_text.setVisible(False)
        self.status_text.setPlaceholderText("提取状态信息将在这里显示")
        progress_layout.addWidget(self.status_text)
        
        progress_group.setLayout(progress_layout)
        layout.addWidget(progress_group)
        
        # 按钮组
        button_layout = QHBoxLayout()
        button_layout.addStretch()
        
        self.extract_btn = QPushButton("开始提取")
        self.extract_btn.clicked.connect(self.start_extraction)
        self.extract_btn.setEnabled(False)
        
        self.stop_btn = QPushButton("停止")
        self.stop_btn.clicked.connect(self.stop_extraction)
        self.stop_btn.setEnabled(False)
        
        button_layout.addWidget(self.extract_btn)
        button_layout.addWidget(self.stop_btn)
        
        layout.addLayout(button_layout)
        
        self.setLayout(layout)
        
    def update_ocr_status(self, message):
        """更新OCR引擎状态"""
        if "完成" in message:
            self.ocr_status_label.setText("✓ " + message)
            self.ocr_status_label.setStyleSheet("color: green; font-weight: bold;")
        elif "失败" in message:
            self.ocr_status_label.setText("✗ " + message)
            self.ocr_status_label.setStyleSheet("color: red; font-weight: bold;")
        else:
            self.ocr_status_label.setText(message)
            self.ocr_status_label.setStyleSheet("color: orange; font-weight: bold;")
            
    def toggle_region_settings(self, checked):
        """切换字幕区域设置显示"""
        self.region_frame.setVisible(not checked)
        
    def set_preset_region(self, preset_type):
        """设置预设字幕区域"""
        if not hasattr(self, 'video_width') or not hasattr(self, 'video_height'):
            QMessageBox.warning(self, "警告", "请先选择视频文件")
            return
            
        if preset_type == "bottom_center":
            # 底部中央
            self.x_spin.setValue(self.video_width // 4)
            self.y_spin.setValue(int(self.video_height * 0.8))
            self.width_spin.setValue(self.video_width // 2)
            self.height_spin.setValue(int(self.video_height * 0.15))
        elif preset_type == "bottom_full":
            # 底部全宽
            self.x_spin.setValue(0)
            self.y_spin.setValue(int(self.video_height * 0.8))
            self.width_spin.setValue(self.video_width)
            self.height_spin.setValue(int(self.video_height * 0.15))
        elif preset_type == "top_center":
            # 顶部中央
            self.x_spin.setValue(self.video_width // 4)
            self.y_spin.setValue(0)
            self.width_spin.setValue(self.video_width // 2)
            self.height_spin.setValue(int(self.video_height * 0.15))
        
    def select_video(self):
        """选择输入视频文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择视频文件", "", 
            "视频文件 (*.mp4 *.avi *.mov *.mkv *.wmv *.flv);;所有文件 (*.*)"
        )
        
        if file_path:
            self.video_path_edit.setText(file_path)
            self.update_video_info(file_path)
            self.auto_set_output_path(file_path)
            self.check_extract_ready()
            
    def select_output(self):
        """选择输出字幕文件路径"""
        file_path, _ = QFileDialog.getSaveFileName(
            self, "保存字幕文件", "", 
            "SRT字幕文件 (*.srt);;所有文件 (*.*)"
        )
        
        if file_path:
            self.output_path_edit.setText(file_path)
            self.check_extract_ready()
            
    def auto_set_output_path(self, video_path):
        """自动设置输出路径"""
        if not self.output_path_edit.text():
            base_name = os.path.splitext(video_path)[0]
            output_path = f"{base_name}_extracted.srt"
            self.output_path_edit.setText(output_path)
            
    def update_video_info(self, video_path):
        """更新视频信息显示"""
        success, info = self.extractor.get_video_info(video_path)
        
        if success:
            self.video_width = info['width']
            self.video_height = info['height']
            
            info_text = f"""视频信息:
分辨率: {info['width']} x {info['height']}
时长: {info['duration']:.2f} 秒
帧率: {info['fps']:.2f} fps
文件大小: {info['size']}"""
            self.video_info_text.setPlainText(info_text)
            
            # 更新预设区域按钮的默认值
            if not self.auto_detect_checkbox.isChecked():
                self.set_preset_region("bottom_center")
        else:
            self.video_info_text.setPlainText(f"获取视频信息失败: {info}")
            
    def check_extract_ready(self):
        """检查是否可以开始提取"""
        if (self.video_path_edit.text() and 
            self.output_path_edit.text()):
            self.extract_btn.setEnabled(True)
        else:
            self.extract_btn.setEnabled(False)
            
    def start_extraction(self):
        """开始字幕提取"""
        video_path = self.video_path_edit.text().strip()
        output_path = self.output_path_edit.text().strip()
        
        if not video_path or not output_path:
            QMessageBox.warning(self, "警告", "请选择输入视频和输出路径")
            return
            
        if not os.path.exists(video_path):
            QMessageBox.critical(self, "错误", "输入视频文件不存在")
            return
            
        # 禁用界面控件
        self.extract_btn.setEnabled(False)
        self.select_video_btn.setEnabled(False)
        self.select_output_btn.setEnabled(False)
        
        # 显示进度界面
        self.progress_bar.setVisible(True)
        self.status_text.setVisible(True)
        self.progress_bar.setValue(0)
        self.status_text.clear()
        
        # 获取参数
        sample_interval = self.interval_spin.value()
        confidence_threshold = self.confidence_slider.value()
        
        # 获取字幕区域设置
        subtitle_region = None
        if not self.auto_detect_checkbox.isChecked():
            subtitle_region = (
                self.x_spin.value(),
                self.y_spin.value(),
                self.width_spin.value(),
                self.height_spin.value()
            )
        
        # 创建提取线程
        self.extraction_thread = SubtitleExtractionThread(
            self.extractor,
            video_path,
            output_path,
            sample_interval,
            confidence_threshold,
            subtitle_region
        )
        
        # 连接信号
        self.extraction_thread.progress_updated.connect(self.update_progress)
        self.extraction_thread.status_updated.connect(self.update_status)
        self.extraction_thread.extraction_finished.connect(self.extraction_finished)
        
        # 启动线程
        self.extraction_thread.start()
        
        # 启用停止按钮
        self.stop_btn.setEnabled(True)
        
    def stop_extraction(self):
        """停止字幕提取"""
        if self.extraction_thread and self.extraction_thread.isRunning():
            self.extraction_thread.terminate()
            self.extraction_thread.wait()
            self.extraction_finished(False, "提取已停止", [])
            
    def update_progress(self, value):
        """更新进度条"""
        self.progress_bar.setValue(value)
        
    def update_status(self, message):
        """更新状态信息"""
        self.status_text.append(message)
        
    def extraction_finished(self, success, message, subtitles):
        """提取完成"""
        # 恢复界面控件
        self.extract_btn.setEnabled(True)
        self.select_video_btn.setEnabled(True)
        self.select_output_btn.setEnabled(True)
        self.stop_btn.setEnabled(False)
        
        # 隐藏进度界面
        self.progress_bar.setVisible(False)
        self.status_text.setVisible(False)
        
        if success:
            QMessageBox.information(self, "成功", f"{message}\n提取了 {len(subtitles)} 条字幕")
            
            # 显示提取结果
            if subtitles and self.show_preview_checkbox.isChecked():
                result_text = "提取结果预览:\n\n"
                for i, subtitle in enumerate(subtitles[:10], 1):  # 只显示前10条
                    start_time = self.format_time(subtitle["start_time"])
                    end_time = self.format_time(subtitle["end_time"])
                    result_text += f"{i:2d}. {start_time} --> {end_time}\n"
                    result_text += f"    {subtitle['text']}\n\n"
                    
                if len(subtitles) > 10:
                    result_text += f"... 还有 {len(subtitles) - 10} 条字幕\n"
                    
                self.status_text.setVisible(True)
                self.status_text.setPlainText(result_text)
        else:
            QMessageBox.critical(self, "错误", message)
            
        # 清理线程
        if self.extraction_thread:
            self.extraction_thread.deleteLater()
            self.extraction_thread = None
            
    def format_time(self, seconds):
        """格式化时间显示"""
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        secs = int(seconds % 60)
        millisecs = int((seconds % 1) * 1000)
        
        return f"{hours:02d}:{minutes:02d}:{secs:02d}.{millisecs:03d}" 